package com.ysh.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import javax.persistence.Query;

import org.apache.log4j.Logger;

import com.util.CalculateMRR;
import com.util.DetailedDecoder;
import com.ysh.gsm.Call;
import com.ysh.gsm.CallMessage;
import com.ysh.gsm.Callleg;
import com.ysh.gsm.CdrMR;
import com.ysh.gsm.KPI;
import com.ysh.gsm.LadderView;
import com.ysh.gsm.MRRView;
import com.ysh.gsm.vos.Column;
import com.ysh.gsm.vos.ThreeSerice;

import com.ysh.gsm.vos.DoubleSerice;

import com.ysh.gsm.vos.SingleReportSerice;

/**
 * @author ysh
 *
 */
public class CallService {
	


	private static Logger logger = Logger.getLogger(CallService.class);

	public CallService() {
		super();
	}
	
	public List<Call> getAllCallsBySql(String sql){
		EntityManagerFactory entityManagerFactory  = PersistenceManager.getInstance().getEntityManagerFactory();
		EntityManager em = entityManagerFactory.createEntityManager();
		Query q = em.createQuery(sql);
		List<Call> calls = q.getResultList();
		if (calls != null)
			logger.debug("** Found " + calls.size() + " records:");
		em.close();
		return calls;
		
	}
	
	public List<Call> getCalls(String unit){
		
		EntityManagerFactory entityManagerFactory  = PersistenceManager.getInstance().getEntityManagerFactory(unit);
		EntityManager em = entityManagerFactory.createEntityManager();
		Query findAllQuery = em.createNamedQuery("calls.findAll");
		List<Call> calls = findAllQuery.getResultList();
		if (calls != null)
			logger.debug("** Found " + calls.size() + " records:");
		em.close();
		return calls;
		
	}
	
	public List<KPI> getAllKPIs(){
		EntityManagerFactory entityManagerFactory  = PersistenceManager.getInstance().getEntityManagerFactory();
		EntityManager em = entityManagerFactory.createEntityManager();
		Query findAllQuery = em.createNamedQuery("kpi.findAll");
		List<KPI> kpis = findAllQuery.getResultList();
		if (kpis != null)
			logger.debug("** Found " + kpis.size() + " records in KPI:");
		em.close();
		return kpis;
		
	}
	public List<Callleg> getCalllegs(long callID){
		EntityManagerFactory entityManagerFactory  = PersistenceManager.getInstance().getEntityManagerFactory();
		EntityManager em = entityManagerFactory.createEntityManager();
		Query qc = em.createNamedQuery("calls.byId");
		qc.setParameter("callKey", callID);
		Call call = (Call) qc.getSingleResult();
		Query q = em.createNamedQuery("cleg.call");
		q.setParameter("call", call);	
		List<Callleg> result=q.getResultList();
		if (result != null)
			logger.debug("** Found " + result.size() + " calllegs");
		return result;
	}
	
	
	public LadderView getLadder(long callID){
		EntityManagerFactory entityManagerFactory  = PersistenceManager.getInstance().getEntityManagerFactory();
		EntityManager em = entityManagerFactory.createEntityManager();
		Query qc = em.createNamedQuery("calls.byId");
		qc.setParameter("callKey", callID);
		Call call = (Call) qc.getSingleResult();
		Query q = em.createNamedQuery("cleg.call");
		q.setParameter("call", call);
		List<Callleg> legs=q.getResultList();
		LadderView lv=new LadderView();	
		lv.setColumns(getCols(legs));
		lv.setMessages(getMsg(legs));
		return lv;
	}
	private List<CallMessage> getMsg(List<Callleg> legs){
		List<CallMessage> msgs=new ArrayList<CallMessage>();
		for(Callleg leg:legs){
			msgs=new DetailedDecoder().getAllMesgs(leg);
		
		}
		if(msgs!=null){
			Collections.sort(msgs, new CustomComparator());
		}
		return msgs;
		
	}
	public class CustomComparator implements Comparator<CallMessage> {
	  
	    public int compare(CallMessage o1, CallMessage o2) {
	        return o1.getDateTime().compareTo(o2.getDateTime());
	    }
	}
	
	private List<Column> getCols(List<Callleg> legs){
		List<Column> cols=new ArrayList<Column>();
		List<Integer> cellIDs=new ArrayList<Integer>();
		cols.add(new Column("UE", 0, 0));
		for(Callleg leg:legs){
			if(cellIDs.contains(leg.getCellId())){
				
			}else{
				cellIDs.add(leg.getCellId());
				cols.add(new Column("Cell"+leg.getCellId(),1,leg.getCellId()));
			}
			
		}
		cols.add(new Column("BSC",2,legs.get(0).getBscId()));
		return cols;
	}

	public List<CdrMR> getCdrMRsByCall(long callID){
		EntityManagerFactory entityManagerFactory  = PersistenceManager.getInstance().getEntityManagerFactory();
		EntityManager em = entityManagerFactory.createEntityManager();
		Query qc = em.createNamedQuery("calls.byId");
		qc.setParameter("callKey", callID);
		Call call = (Call) qc.getSingleResult();
		Query q = em.createNamedQuery("cmr.findByCall");
		q.setParameter("call", call);
		List<CdrMR> cdrs = q.getResultList();
		if (cdrs != null)
			logger.debug("** Found cdrmr" + cdrs.size() + " records:");
		em.close();
		decorateCdrs(cdrs);
		return cdrs;		
	}
	private void decorateCdrs(List<CdrMR> cdrs){
		if(cdrs==null||cdrs.size()==0){
			return;
		}
		for (CdrMR cdr:cdrs){
			if(cdr.getDtxUsed()==1){
				cdr.setRxlevFull(cdr.getRxlevSub());
				cdr.setRxqualFull(cdr.getRxqualSub());
				cdr.setSerCellRxlevFull(cdr.getSerCellRxlevSub());
				cdr.setSerCellRxqualFull(cdr.getSerCellRxqualSub());
			}
			
		}
	}
	public MRRView getCdrMRsByCell(byte cell){
		EntityManagerFactory entityManagerFactory  = PersistenceManager.getInstance().getEntityManagerFactory();
		EntityManager em = entityManagerFactory.createEntityManager();

		Query q = em.createNamedQuery("cmr.findByCell");
		q.setParameter("cellId", cell);
		List<CdrMR> cdrs = q.getResultList();
		if (cdrs != null)
			logger.debug("** Found cdrmr" + cdrs.size() + " records:");
		em.close();
		
		return getReportData(cdrs);
		
	}
	public MRRView getMrrBySql(String sql){
		EntityManagerFactory entityManagerFactory  = PersistenceManager.getInstance().getEntityManagerFactory();
		EntityManager em = entityManagerFactory.createEntityManager();
		Query q = em.createQuery(sql);
		List<CdrMR> cdrs = q.getResultList();
		if (cdrs != null)
			logger.debug("** Found cdrmr" + cdrs.size() + " records:");
		em.close();
		
		return getReportData(cdrs);
		
	}
	private MRRView getReportData(List<CdrMR> cdrs){
		long start=System.nanoTime();
		int []ta=new int[cdrs.size()];
		int []rxqUp=new int[cdrs.size()];
		int []rxqDn=new int[cdrs.size()];
		int []rxlUp=new int[cdrs.size()];
		int []rxlDn=new int[cdrs.size()]; 
		int []bms=new int[cdrs.size()];
		int []pms=new int[cdrs.size()];
		int i=0;
		for(CdrMR cm:cdrs){
			ta[i]=cm.getActTa();
			bms[i]=cm.getBsPowerLev();
			pms[i]=cm.getMsPowerLev();
			if(cm.getDtxUsed()==1){
				rxqUp[i]=cm.getRxqualSub();
				rxqDn[i]=cm.getSerCellRxqualSub();
				rxlUp[i]=cm.getRxlevSub();
				rxlDn[i]=cm.getSerCellRxlevSub();
			}else{
				rxqUp[i]=cm.getRxqualFull();
				rxqDn[i]=cm.getSerCellRxqualFull();
				rxlUp[i]=cm.getRxlevFull();
				rxlDn[i]=cm.getSerCellRxlevFull();
			}
			i++;
		}
		CalculateMRR mrr=new CalculateMRR();
		List<DoubleSerice> rxq= mrr.calcDoub(rxqUp, rxqDn, 0, 8);
		List<DoubleSerice> rxl= mrr.calcDoub(rxlUp, rxlDn, -110, -46);
		List<SingleReportSerice> rTa=mrr.calcSing(ta);
		List<SingleReportSerice> rpbs=mrr.calcSing(bms);
		List<SingleReportSerice> rpms=mrr.calcSing(pms);
		List<ThreeSerice> rxqta=mrr.calcThree(ta,rxqUp,rxqDn);
	
		MRRView mview=new MRRView();
		mview.setRxq(rxq);
		mview.setRxl(rxl);
		mview.setRta(rTa);
		mview.setPbs(rpbs);
		mview.setPms(rpms);
		mview.setRxta(rxqta);
		System.out.println("time:"+(System.nanoTime()-start));
		return mview;
	}
	public LadderView getMockLadd(){		
		LadderView lv=new LadderView();		
		lv.setColumns(mockCols());
		lv.setMessages(mockMsgs());	
		return lv;		
	}
	private List<Column> mockCols(){		
		List<Column> cols=new ArrayList<Column>();
		cols.add(new Column("UE",0,0));
		cols.add(new Column("Cell2",1,2));
		cols.add(new Column("Cell1",1,1));
		cols.add(new Column("BSC1",2,1));	
		return cols;
		
	}
	private List<CallMessage> mockMsgs(){
		
		List<CallMessage> msgs=new ArrayList<CallMessage>();
		short bin=0;
		byte c1=0;
		byte c2=1;
		byte c3=6;
		byte[] bi={};	
		Date dd=new Date();
		long dt=dd.getTime();		
		msgs.add(new CallMessage(new Date(dt),"msg1",c3,c2,bin,bin,bi,"",1,1));
		msgs.add(new CallMessage(new Date(dt-5000),"msg2",c2,c1,bin,bin,bi,"",1,2));
		msgs.add(new CallMessage(new Date(dt-10000),"msg3",c2,c2,bin,bin,bi,"",1,1));
		msgs.add(new CallMessage(new Date(dt-15000),"msg4",c3,c1,bin,bin,bi,"",1,1));
		msgs.add(new CallMessage(new Date(dt-20000),"msg5",c2,c2,bin,bin,bi,"",1,2));		
		return msgs;
	}

}
